package org.douxiaoban.client.api;

import java.util.ArrayList;
import java.util.List;

import org.douxiaoban.client.R;
import org.douxiaoban.client.adapter.DoubanAdapter;
import org.douxiaoban.client.adapter.MailAdapter;
import org.douxiaoban.client.app.App;
import org.douxiaoban.client.app.Assistant;
import org.douxiaoban.client.util.ThreadTool;
import org.douxiaoban.client.util.ThreadTool.DoubanListSerialz;
import org.douxiaoban.client.widget.ElasticListView;
import org.douxiaoban.client.widget.ElasticListView.OnRefreshListener;



import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;

/**
 * 
* Description:  
* 			一个抽象类，所有的包含listView的类 
* 			包含了adapter，以及对listView的一些操作如监听滚动，单击，及长按等
* 			以及progressbar的显示隐藏等
* Copyright:   Copyright (c)2011  
* @author:     6a209  
* Create at:   2011-7-14 上午10:55:40
 */
public abstract class DoubanList {

	public enum DoubanListType {
		MAIL_INBOX,
		MAIL_OUTBOX,
		FRIENDS,
		CONTACTS,
		CONTACTS_MINIBLOG,
		USER_MINIBLOG
	}
	
	protected View mMainView;
	protected View mProgressBar;
	protected ElasticListView mListView;
	protected DoubanAdapter mAdapter;
	protected DoubanListType mType;
	
	protected int mCount;
	protected int mFirstId;
	protected int mLastId;
	
	protected boolean mIsEnd;
	protected boolean mIsFirst;
	protected boolean mIsUpdateing;
//	//获取更多的时候的补偿,当去获取更多时有更新(等新的api把!)
//	private int mCompensateCount;
	private Context mContext;
	
	private String mUserId;
	private View mFootView;
	
	//-------------------抽象方法-----------------------------------------------------------------
	/**
	 * listView 长按监听事件
	 */
	public abstract boolean longClickEvent
			(AdapterView<?> arg0, View arg1, int index, long id);
	
	/**
	 * 
	* listView 短按监听事件
	* @param  
	* @return 
	* @exception
	 */
	public abstract void clickEvent
			(AdapterView<?> arg0, View arg1, int index, long id);
	

	
	//！-------------------抽象方法-----------------------------------------------------------------

	
	public DoubanList
		(Context context,DoubanAdapter adapter, DoubanListType type){
		
		mContext = context;
		LayoutInflater flater = LayoutInflater.from(context);
		mMainView = flater.inflate(R.layout.list, null);
		init(adapter, type);		
	}
	
	//used to Miniblog
	//miniblog's view contain a response dlg 
	//so you need the mainView
	public DoubanList(Context context, DoubanAdapter adapter, 
			DoubanListType type, View mainView){
		mContext = context;
		mMainView = mainView;
		init(adapter, type);
	}
	
	// use UserMiniblog
	//when to some people' home you must user get the uesId 
	//to get data;
	public DoubanList(Context context, DoubanAdapter adapter,
			DoubanListType type, View mainView, String userId){
		this(context, adapter, type, mainView);
		mUserId = userId;
	}
	
	private void init(DoubanAdapter adapter, DoubanListType type){
		LayoutInflater flater = LayoutInflater.from(mContext);
		mListView = (ElasticListView)mMainView.findViewById(R.id.listView);
		mProgressBar = mMainView.findViewById(R.id.listProgressBar);
		mAdapter = adapter;
		mFootView = flater.inflate(R.layout.foot, null);
		mUserId = App.userId;
		mListView.setOnRefreshListener(new OnRefreshListener(){
		     @Override
	            public void onRefresh() {
		    	 refresh();
	            }
		});
		
		mListView.addFooterView(mFootView);
		mListView.setAdapter(mAdapter);
		mType = type;
		reset();
		initListener();
		
	}
	
	//-----------------------------更新列表数据----------------------------------------
	private Handler mHandler = new Handler(){
		@Override
		public void handleMessage(Message msg){
			Bundle bundle = msg.getData();
			DoubanListSerialz serialz = 
					(DoubanListSerialz) bundle.getSerializable(Assistant.KEY_DOUBAN_LIST_DATA);
			ArrayList<? extends DoubanData> list = serialz.getList();
			boolean isRefresh = serialz.getIsRefresh();
			switch(msg.what){
			case Assistant.MSG_DOUBAN_LIST_DATA:
				if(isRefresh){
					insertNewData(list);
				}else{
					appendOldData(list);
				}
				setIsUpdateing(false);
			default:
				break;
			}
		}

	};
	
	/**
	 * 获取更多之后，对数据进行刷新操作
	* @param  
	* @return 
	* @exception
	 */
	private void appendOldData(ArrayList<? extends DoubanData> list){
		
		if(0 == list.size()){
			Log.v("updateMiniBlog::itemData size", String.valueOf(list.size()));
			setIsEnd(true);
			return;
		}
		//user list no id
		if(DoubanListType.CONTACTS != mType && DoubanListType.FRIENDS != mType){
			int start = getOldIndex(list, getLastId());
			if(-1 == start){
				setCount(getCount() + App.max);
				setIsUpdateing(true);
				getMore();
				return;
			}
			//悲剧的api..不知道神马时候能更新
			List<? extends DoubanData> sub = list.subList(start, list.size());
			list = new ArrayList<DoubanData>(sub);	
		}

		getAdapter().addDataTail(list);
		setCount(getCount() + list.size());
		setIsFirst(false);
		
		//更新最后一个id
		updateLastId();
	}
	
	private void insertNewData(ArrayList<? extends DoubanData> list){
		mListView.onRefreshComplete();
		if(null == list){
			return;
		}
		
		getProgressBar().setVisibility(View.GONE);
		getListView().setVisibility(View.VISIBLE);
		//user list no id
		if(DoubanListType.CONTACTS != mType && DoubanListType.FRIENDS != mType){
			int index = getNewIndex(list, getFirstId());
			if(-1 == index){
				return;
			}
			List<? extends DoubanData> sub = list.subList(0, index);
			list = new ArrayList<DoubanData>(sub);
		}
		getAdapter().addDataPre(list);
		//第一次获取数据
		if(getIsFirst()){
			updateLastId();
			setIsFirst(false);
			setCount(getCount() + list.size());
		}
		updateFirstId();
		//补偿留给addmore
		//this.setCount(this.getCount() + index);
		setIsUpdateing(false);
	}
	
	private void updateLastId(){
		int id = getAdapter().getLastId();
		setLastId(id);
	}
	
	//更新firstID  
	private void updateFirstId(){
		int id = getAdapter().getFirstId();
		setFirstId(id);
	}
	
	/**
	 * 刷新时的位置分析
	* @param  
	* @return 返回-1，是因为刷新的数据全都是旧的
	* @exception
	 */
	private int getNewIndex(ArrayList<? extends DoubanData> list, int id){
		for(int index = list.size()-1; index >=0 ; index--){
			if(list.get(index).mId > id){
				//作为右边界
				return index + 1;
			}			
		}
		return -1;
	}
	
	/**
	 * 获取更多时候的位置分析
	 * @param list 获取到的数据
	 * @param id   当前最后一个item的id值
	 * @return 返回-1 是因为获取更多时此时你的contacts已经发了大于20条广播
	 */
	private int getOldIndex(ArrayList<? extends DoubanData> list, int id){
		for(int index = 0; index != list.size(); index++){
			if(list.get(index).mId < id){
				return index;
			}			
		}
		return -1;
	}
	//！-----------------------------更新列表数据----------------------------------------
	
	
	//------------------------------获取数据列表---------------------------------------------
	public  void getMore(){
		int start = getCount() + 1;
		getListData(mUserId, start, App.max, false);
	}
	
	public  void refresh(){
//		mHeadRefresh.setText("获取数据");
//		mHeadProgressBar.setVisibility(View.VISIBLE);
		
		int start = 1;
		getListData(mUserId, start, App.max, true);
	}

	/**
	 * 获取列表数据操作,在getore，和refresh中会操作
	* @param  userId :  针对要获取数据的用户
	* @param  max: 一次获取的最大条数
	* @param  isRefresh : 是否是刷新操作
	* @return 
	* @exception
	 */
	protected  void getListData(String userId, int start, int max, boolean isRefresh){
		DoubanList.DoubanListType type = getType();
		ThreadTool.instace(mContext).getListData(mHandler, userId, start, max, type, isRefresh);
	}
	//！------------------------------获取数据列表---------------------------------------------
	
	
	
	//---------------------监听事件--------------------------------------------------------------------------------
	/**
	 *  滚动监听
	* @param  
	* @return 
	* @exception
	 */
	public  void scrollEvent(AbsListView v,
							 int firstVisbleItem,
							 int visibleItemCount,
							 int totalItemCount){
		
		if(firstVisbleItem + visibleItemCount == totalItemCount 
			&& !getIsUpdateing() 
			&& !getIsEnd()
			&& 0 != firstVisbleItem){
			
				setIsUpdateing(true);
				getMore();
			}
		
	}

	
	
	private void initListener(){
		
		//短按
		mListView.setOnItemClickListener(new OnItemClickListener(){
			@Override
			public void onItemClick(AdapterView<?> adapter, View view, int index, long id){
				clickEvent(adapter, view, index, id);
			}
		});
		
		//长按 
		mListView.setOnItemLongClickListener(new OnItemLongClickListener(){
			@Override
			public boolean onItemLongClick(AdapterView<?> adapter, View view, int index, long id){
				return longClickEvent(adapter, view, index, id);
			}
		});
		
		//滚动
		mListView.setOnScrollListener(new OnScrollListener(){
			@Override
			public void onScroll(AbsListView v, int firstVisbleItem, int visibleItemCount, int totalItemCount){
				scrollEvent(v, firstVisbleItem, visibleItemCount, totalItemCount);
			}
			
			@Override
			public void onScrollStateChanged(AbsListView arg0, int arg1){
				
			}
			
		});
	}
	
	//！---------------------监听事件--------------------------------------------------------------------------------
	
	public void reset(){
		mCount = 0;		
		mFirstId = -1;
		mLastId = -1;	
		
		mIsEnd = false;
		mIsFirst = true;
		mIsUpdateing = false;
	}
	
	public void updateFootView(){
		ProgressBar pgb = (ProgressBar)mFootView.findViewById(R.id.footProgressBar);
		pgb.setVisibility(View.GONE);
		TextView textView = (TextView)mFootView.findViewById(R.id.footTextView);
		textView.setText("End");
	}
	
	//-------------------get && set ------------------------------------------
	public View getMainview(){
		return mMainView;
	}
	public void setMainView(View v){
		mMainView = v;
	}
	
	public View getProgressBar(){
		return mProgressBar;
	}	
	public void setProgressBar(View v){
		mProgressBar = v;
	}
	
	public ListView getListView(){
		return mListView;
	}
	public void setListView(ElasticListView v){
		mListView = v;
	}
	
	public DoubanAdapter getAdapter(){
		return mAdapter;
	}
	public void setAdapter(DoubanAdapter adapter){
		mAdapter = adapter;
	}
	
	public DoubanListType getType(){
		return mType;
	}
	public void setType(DoubanListType type){
		mType = type;
	}
	
	public int getCount(){
		return mCount;
	}
	
	public void setCount(int count){
		mCount = count;
	}
	
	public int getFirstId(){
		return mFirstId;
	}
	public void setFirstId(int id){
		mFirstId = id;
	}
	
	public int getLastId(){
		return mLastId;
	}
	public void setLastId(int id){
		mLastId = id;
	}
	
	public boolean getIsFirst(){
		return mIsFirst;
	}
	public void setIsFirst(boolean b){
		mIsFirst = b;
	}
	
	public boolean getIsUpdateing(){
		return mIsUpdateing;
	}
	
	public void setIsUpdateing(boolean b){
		mIsUpdateing = b;
	}
	
	public boolean getIsEnd(){
		return mIsEnd;
	}
	public void setIsEnd(boolean b){
		mIsEnd = b; 
	    if(b){
	    	mFootView.findViewById(R.id.footProgressBar).setVisibility(View.GONE);
	    	((TextView)mFootView.findViewById(R.id.footTextView)).setText("木有数据了！");
	    }
	}
	public String getmUserId() {
		return mUserId;
	}

	public void setmUserId(String mUserId) {
		this.mUserId = mUserId;
	}

}